<template>
  <n-data-table
    ref="$table"
    class="ganttTable"
    :style="{ width: `${colWidth}px` }"
    :columns="columns"
    :data="props.list"
    :bordered="true"
    :single-line="false"
    :row-key="(row) => row['exeId'] || row['id']"
    :row-props="rowProps"
    :max-height="505"
    flex-height
    @scroll="(e) => emits('scroll', e)"
  />
</template>
<script setup lang="jsx">
import dayjs from 'dayjs'
import { Bell } from '@vicons/tabler'
import { usePermissionStore } from '@/store'
import * as taskProjectApi from '@/api/taskProject'
import { watchEffect } from 'vue'
defineOptions({ name: 'TaskTable' })
const props = defineProps({
  // all | self
  scene: {
    type: String,
    default: 'all',
  },
  list: {
    type: Array,
    default: () => [],
  },
  haveColumnKeys: {
    type: Array,
    default: () => [],
  },
})
const emits = defineEmits(['scroll', 'contextmenu', 'changeWidth', 'reset'])
const router = useRouter()
const { hasPermission } = usePermissionStore()
const isSelf = computed(() => props.scene === 'self')
const isDrag = computed(() => isSelf.value && hasPermission('TaskModule:drag'))
//状态枚举
const statusOptions = [
  { label: '未开始', value: 0, color: '#f0f1f4' },
  { label: '进行中', value: 1, color: '#FCDF7E' },
  { label: '已完成', value: 2, color: '#95E599' },
]
//跳转项目详情
async function toDetail(projectId) {
  if (hasPermission('project_view')) {
    $message.loading('', { key: 'query' })
    taskProjectApi
      .canView({ projectId })
      .then((res) => {
        if (res.data) {
          $message.destroy('query')
          router.push({ path: `/project/detail`, query: { id: projectId } })
        } else {
          $message.destroy('query')
          $message.warning(`非当前项目成员!`)
        }
      })
      .catch(() => {
        $message.destroy('query')
        $message.warning(`校验失败!`)
      })
  } else {
    $message.warning(`暂无权限!`)
  }
}
//项目
const projectCol = {
  title: '项目',
  key: 'name0',
  width: 90,
  rowSpan: (row) => props.list.filter((item) => item.id0 === row.id0).length,
  render: ({ id0, name0, projectVersion, projectVersionMinor }) => {
    let count = props.list.filter((item) => item.id0 === id0).length
    return (
      <div
        class="w-100% cursor-pointer color-#0A56D8 underline"
        style={{
          whiteSpace: 'normal',
          wordBreak: 'break-all',
          wordWrap: 'break-word',
          maxHeight: `${count * 30 - 8}px`,
        }}
        onClick={() => toDetail(id0)}
      >
        <n-ellipsis line-clamp={count}>
          {`${name0} V.${projectVersion || 0}.${projectVersionMinor || 0}`}
        </n-ellipsis>
      </div>
    )
  },
}
//一级模块
const oneCol = {
  title: '一级模块',
  key: 'name1',
  width: 90,
  ellipsis: {
    tooltip: true,
  },
  cellProps: (row) =>
    row.id1 ? { 'data-mid': row.id1, 'data-pid': row.id0, draggable: isDrag.value } : {},
  rowSpan: (row) =>
    props.list.filter((item) => item.id0 === row.id0 && item.id1 === row.id1).length,
  render: ({ name1 }) => name1 || '--',
}
//二级模块
const twoCol = {
  title: '二级模块',
  key: 'name2',
  width: 90,
  ellipsis: {
    tooltip: true,
  },
  cellProps: (row) =>
    row.id2 ? { 'data-mid': row.id2, 'data-pid': row.id1, draggable: isDrag.value } : {},
  rowSpan: (row) =>
    props.list.filter(
      (item) => item.id0 === row.id0 && item.id1 === row.id1 && item.id2 === row.id2
    ).length,
  render: ({ name2 }) => name2 || '--',
}
//三级模块
const threeCol = {
  title: '三级模块',
  key: 'name3',
  width: 90,
  ellipsis: {
    tooltip: true,
  },
  cellProps: (row) =>
    row.id3 ? { 'data-mid': row.id3, 'data-pid': row.id2, draggable: isDrag.value } : {},
  rowSpan: (row) =>
    props.list.filter(
      (item) =>
        item.id0 === row.id0 && item.id1 === row.id1 && item.id2 === row.id2 && item.id3 === row.id3
    ).length,
  render: ({ name3 }) => name3 || '--',
}
//执行人
const personCol = {
  title: '执行人',
  key: 'executorName',
  width: 100,
  resizable: true,
  minWidth: 80,
  maxWidth: 200,
  render({ executor, avatar, executorName, taskState, startTime }) {
    if (executor) {
      let tip = taskState === 0 && dayjs().isAfter(dayjs(startTime))
      return (
        <MyInfo src={avatar} text={executorName} shrink={true}>
          {{
            after: () => (tip ? <n-icon component={Bell} color="red" size="16" /> : null),
          }}
        </MyInfo>
      )
    } else {
      return '--'
    }
  },
}
//执行范围
const scopeCol = {
  title: '执行范围',
  width: 90,
  resizable: true,
  minWidth: 60,
  maxWidth: 300,
  key: 'executionScope',
  ellipsis: {
    tooltip: true,
  },
  render: ({ executionScope }) => executionScope || '--',
}
//评估
const estimateCol = {
  title: '评估',
  width: 55,
  resizable: true,
  minWidth: 30,
  maxWidth: 100,
  key: 'duration',
  render: ({ duration }) => duration || '--',
}
//排期
const schedulesCol = {
  title: '排期',
  width: 55,
  resizable: true,
  minWidth: 30,
  maxWidth: 100,
  key: 'realityduration',
  render: ({ realityduration }) => realityduration || '--',
}
//状态
const statusCol = {
  title: '状态',
  key: 'taskState',
  width: 70,
  resizable: true,
  minWidth: 50,
  maxWidth: 70,
  render({ taskState, endTime }) {
    if (taskState === undefined) {
      return '--'
    } else {
      let customColor = dayjs().isAfter(dayjs(endTime)) && [0, 1].includes(taskState) ? 'red' : ''
      return (
        <MyStatus
          type="card"
          options={statusOptions}
          value={taskState}
          labelKey="label"
          valueKey="value"
          customColor={customColor}
        />
      )
    }
  },
}
const columns = computed(() => [
  {
    title: '序号',
    key: 'index',
    width: 60,
    render: (_, index) => index + 1,
  },
  ...(!isSelf.value ? [projectCol] : []),
  ...(props.haveColumnKeys.includes('one') ? [oneCol] : []),
  ...(props.haveColumnKeys.includes('two') ? [twoCol] : []),
  ...(props.haveColumnKeys.includes('three') ? [threeCol] : []),
  ...(props.haveColumnKeys.includes('person') ? [personCol] : []),
  ...(props.haveColumnKeys.includes('scope') ? [scopeCol] : []),
  ...(props.haveColumnKeys.includes('estimate') ? [estimateCol] : []),
  ...(props.haveColumnKeys.includes('schedules') ? [schedulesCol] : []),
  ...(props.haveColumnKeys.includes('status') ? [statusCol] : []),
])
const colWidth = computed(() => columns.value.reduce((sum, item) => (sum += item.width), 0))
watchEffect(() => {
  emits('changeWidth', colWidth.value)
})
function rowProps(row) {
  return {
    style: 'cursor: pointer;height:32px',
    onContextmenu: (e) => {
      console.log(row, e)
      e.preventDefault()
      emits('contextmenu', e, row)
    },
  }
}

const $table = ref(null)
const isBind = ref(false)
function findTd(event) {
  return event.target.closest('.n-data-table-td')
}
function bindDrag() {
  if (isDrag.value && !isBind.value) {
    isBind.value = true
    let beferId = null,
      beferPid = null,
      afterId = null,
      afterPid = null
    const container = $table.value.$el.querySelector('.n-data-table-tbody')
    // 开始拖拽
    container.addEventListener('dragstart', (event) => {
      // console.log('start', event, event.target.getAttribute('data-pid'))
      event.dataTransfer.effectAllowed = 'move'
      beferId = event.target.getAttribute('data-mid')
      beferPid = event.target.getAttribute('data-pid')
    })
    // 移动
    container.addEventListener('dragover', (event) => {
      // console.log('dragover', event, findTd(event))
      if (findTd(event).getAttribute('data-pid') === beferPid) {
        // console.log('可以')
        event.preventDefault()
      } else {
        // console.log('不可以')
      }
    })
    // 进入
    container.addEventListener('dragenter', (event) => {
      // console.log('dragenter', event, findTd(event))
      if (findTd(event).getAttribute('data-pid') === beferPid) {
        findTd(event).classList.add('drag-active')
      }
    })
    // 离开
    container.addEventListener('dragleave', (event) => {
      // console.log('dragleave', event, findTd(event))
      if (event.target.getAttribute('data-pid')) {
        event.target.classList.remove('drag-active')
      }
    })
    // 松手放置
    container.addEventListener('drop', (event) => {
      // console.log('drop', event)
      event.preventDefault()
      findTd(event).classList.remove('drag-active')
      afterId = findTd(event).getAttribute('data-mid')
      afterPid = findTd(event).getAttribute('data-pid')
      // console.log(beferId, beferPid, afterId, afterPid)
      if (beferId && afterId && beferId !== afterId && beferPid === afterPid) {
        // console.log('可以替换')
        handleSort(beferId, afterId)
      }
    })
  }
}
async function handleSort(beferId, afterId) {
  taskProjectApi.sortModule({ beferId, afterId }).then(() => {
    emits('reset')
  })
}
defineExpose({
  bindDrag,
  scrollTo(params) {
    $table?.value?.scrollTo(params)
  },
})
</script>
<style lang="scss">
.ganttTable.n-data-table {
  .drag-active,
  .n-data-table-td[data-menu-active='active'] {
    background-color: #0a56d8 !important;
    color: #fff !important;
  }
  .n-data-table-thead {
    height: 75px;
    background-color: transparent !important;
  }
  .n-data-table-td {
    box-sizing: border-box;
    padding: 4px;
    text-align: left;
  }
  .n-data-table-th,
  .n-data-table-table {
    background-color: transparent !important;
  }
  .n-data-table {
    --n-merged-th-color-hover: transparent;
    --n-merged-td-color-hover: transparent;
    // --n-merged-td-color-hover: RGBA(218, 230, 249, 1);
  }
  .n-data-table-tr:last-of-type {
    height: 17px !important;
  }
  .n-data-table-tr:last-of-type > td {
    display: none !important;
  }
}
</style>
